<?php

/**
 * Description of VirtualLabs_Admin_Machines
 *
 * @author markos
 */
class VirtualLabs_Admin_Machine extends VirtualLabs_Admin_Dao {

    const TABLE_NAME = 'maquina_virtual';
    const TABLE_NAME_AS = 'maquina_virtual_usuario';
    const ESTADO_CREACION = 'C'; // Creacion
    const ESTADO_ACTIVO = 'A'; // Activo 
    const ESTADO_APAGADO = 'D'; // Down
    const ESTADO_ENCENDIDO = 'running'; // Down
    const ESTADO_POWEROFF = 'stopped'; // Down
    const ESTADO_ERROR = 'E'; // Error
    const ESTADO_PENDIENTE = 'P'; // Pendiente

    private $debugLog;
    private $errorLog;

    public function __construct() {
        $this->debugLog = Zend_Registry::get(VirtualLabs_Common::DEBUG_LOG);
        $this->errorLog = Zend_Registry::get(VirtualLabs_Exception::ERROR_LOG);
    }

    /**
     * Retorna los datos de cloudstack de una maquina virtual.
     * 
     * @param string $vmId identificador uuid de la maquina virtual
     * @return mixed $vm array con la informacion de la maquina virtual
     * @throws Exception $e en caso de ocurrir una excepcion la misma se hace flotar
     */
    public function getVmData($vmId) {
        $vmCloud = new VirtualLabs_Rest_VirtualLabs_VirtualMachine();
        try {
            $vm = $vmCloud->listVM($vmId);
//            $this->debugLog->debug(print_r(Zend_Json_Decoder::decode($vm), true));
            return Zend_Json_Decoder::decode($vm);
        } catch (Exception $e) {
            $this->debugLog->err($e->getMessage());
            $this->debugLog->err($e->getTraceAsString());
        }
    }

    /**
     * Recupera el id de la maquina en el cloud stack y envia una solicitud
     * de encendido. 
     * La solicitud se procesa de manera asincrona, por lo tanto la peticion
     * retorna un jobid.
     * 
     * @param string $codigoMaquinaVirtual uuid en cloudstack de la maquina virtual
     * @return mixed respuesta de la peticion al cloudstack
     */
    public function encenderVM($codigoVM) {
        $vmCloud = new VirtualLabs_Rest_VirtualLabs_VirtualMachine();
        try {
            $vmCloudData = $vmCloud->encenderVM($codigoVM);
            return Zend_Json_Decoder::decode($vmCloudData);
        } catch (Exception $e) {
            $this->debugLog->err($e->getMessage());
            $this->debugLog->err($e->getTraceAsString());
        }
    }

    /**
     * Recupera el id de la maquina en el cloud stack y envia una solicitud
     * de apagado. 
     * La solicitud se procesa de manera asincrona, por lo tanto la peticion
     * retorna un jobid.
     * 
     * @param string $codigoMaquinaVirtual uuid en cloudstack de la maquina virtual
     * @return mixed respuesta de la peticion al cloudstack
     */
    public function apagarVM($codigoVM) {
        $vmCloud = new VirtualLabs_Rest_VirtualLabs_VirtualMachine();
        try {
            $vmCloudData = $vmCloud->apagarVM($codigoVM);
            return Zend_Json_Decoder::decode($vmCloudData);
        } catch (Exception $e) {
            $this->debugLog->err($e->getMessage());
            $this->debugLog->err($e->getTraceAsString());
        }
    }

    /**
     * Recupera los datos de las maquias virtuales que se correspondan con la 
     * condicion de busqueda.
     * 
     * @param array $fields arreglo asociativo de campos
     * @param array $where array asociativo de condiciones de busqueda array($key => array($criteria => <=|like|<>|...>, $value => <value>))
     * @return mixed datos de las maquinas virtuales
     * @throws Exception 
     */
    public function getVirtualMachines($fields = array(), $where = array()) {        
        $db = Zend_Db_Table::getDefaultAdapter();
        $select = $db->select()->from("maquina_virtual", $fields);        
        foreach ($where as $key => $value) {
            $select->where("$key {$value['criteria']} ?", $value['value']);
        }

        try {            
            return $db->fetchAll($select);
        } catch (Exception $e) {

            $this->errorLog->err($e->getMessage());
            $this->errorLog->err($e->getTraceAsString());
            throw $e;
        }
    }

    public function getVirtualMachine($fields = array(), $where = array()) {
        $db = Zend_Db_Table::getDefaultAdapter();
        $select = $db->select()->from("maquina_virtual", $fields);
        foreach ($where as $key => $value) {
            $select->where("$key {$value['criteria']} ?", $value['value']);
        }        
        
        try {
            return $db->fetchRow($select);
        } catch (Exception $e) {
            $this->errorLog->err($e->getMessage());
            $this->errorLog->err($e->getTraceAsString());
            throw $e;
        }
    }

    /**
     * Recupera la cantidad de VMs activas.
     * 
     */
    public function getActiveMachines() {
        $db = Zend_Db_Table::getDefaultAdapter();
        try {
            $select = $db->select()->from("maquina_virtual", array("cuenta" => "count(*)"))
                    ->where("encendido = ?", "1");
        } catch (Exception $e) {
            $this->errorLog->debug($e->getMessage());
            $this->errorLog->debug($e->getTraceAsString());
            throw $e;
        }
        return $db->fetchRow($select);
    }

    /**
     * Recupera la cantidad total de VMs.
     * 
     */
    public function getAllMachines() {
        $db = Zend_Db_Table::getDefaultAdapter();
        try {
            $select = $db->select()->from("maquina_virtual", array("cuenta" => "count(*)"));
        } catch (Exception $e) {
            $this->errorLog->debug($e->getMessage());
            $this->errorLog->debug($e->getTraceAsString());
            throw $e;
        }
        return $db->fetchRow($select);
    }

    public function getVirtualMachinesByLab($laboratorio) {
        $db = Zend_Db_Table::getDefaultAdapter();
        $select = $db->select()->from(array("vm" => "maquina_virtual"), array("codigo_maquina_virtual",
                    "codigo_laboratorio", "codigo_vm", "estado", "url"))
                ->where("codigo_laboratorio = ?", $laboratorio);
        try {

            $result = $db->fetchAll($select);
        } catch (Exception $e) {
            $this->errorLog->debug($e->getMessage());
            $this->errorLog->debug($e->getTraceAsString());
            throw $e;
        }
        return $result;
    }

    /* Elimina los permisos asociados al codigo de laboratorio en la TABLA MIEMBROS_LABORATORIO
     * 
     * @param $code array(index, value)
     * $codigoRol = array('key' => 'codigo_rol', 'value' => $codigo_rol);
     */

    public function deleteMiembrosAsociadosVM($code) {
        try {
            $this->delete(VirtualLabs_Admin_Machine::TABLE_NAME_AS, $code);
            return true;
        } catch (Exception $e) {
            $logger = Zend_Registry::get(VirtualLabs_Exception::ERROR_LOG);
            $logger->err($e->getMessage());
            $logger->err($e->getTraceAsString());
            throw $e;
        }
    }
    
    public function deleteVM($code) {
        try {
            $this->delete(VirtualLabs_Admin_Machine::TABLE_NAME, $code);
            return true;
        } catch (Exception $e) {
            $logger = Zend_Registry::get(VirtualLabs_Exception::ERROR_LOG);
            $logger->err($e->getMessage());
            $logger->err($e->getTraceAsString());
            throw $e;
        }
    }

    public function insertMiembroAsociado($codigoVM, $username) {
        try {
            $data = array(
                'codigo_maquina_virtual' => $codigoVM,
                'username' => $username,
                'secuencia' => 0,
                'username_creador' => 'markosbenitez'
            );
            $db = Zend_Db_Table::getDefaultAdapter();

            $debug = Zend_Registry::get(VirtualLabs_Common::DEBUG_LOG);
            $debug->debug("Insertando miembro asociado: " . print_r($data, true));

            $db->insert(VirtualLabs_Admin_Machine::TABLE_NAME_AS, $data);
            return true;
        } catch (Exception $e) {
            $logger = Zend_Registry::get(VirtualLabs_Exception::ERROR_LOG);
            $logger->err($e->getMessage());
            $logger->err($e->getTraceAsString());
            throw $e;
        }
    }

}
?>

